package com.seadragon.app.ksr.dao.jpa;

import java.util.Collection;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.seadragon.app.ksr.dao.CategoryDao;
import com.seadragon.app.ksr.model.Category;

@Repository("categoryDao")
@Transactional
public class CategoryDaoJpaImpl extends AbstractJpaDao implements CategoryDao {

	@Override
	public List<Category> findAll() {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Category> cq = cb.createQuery(Category.class);
		Root<Category> root = cq.from(Category.class);
		cq.select(root);
		return entityManager.createQuery(cq).getResultList();
	}

	@Override
	public List<Category> findAllByLevel(int level) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Category> cq = cb.createQuery(Category.class);
		Root<Category> root = cq.from(Category.class);
		cq.select(root);
		cq.where(cb.equal(root.get("level"), level));
		return entityManager.createQuery(cq).getResultList();
	}

	@Override
	public List<Category> findAllLeafCategory() {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Category> cq = cb.createQuery(Category.class);
		Root<Category> root = cq.from(Category.class);
		cq.select(root).distinct(true);
		Expression<Collection<Category>> children = root.get("children");
		cq.where(cb.isEmpty(children));
		return entityManager.createQuery(cq).getResultList();
	}

	@Override
	public void save(Category category){
		entityManager.persist(category);
	}

	@Override
	public Category findByName(String name) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Category> cq = cb.createQuery(Category.class);
		Root<Category> root = cq.from(Category.class);
		cq.select(root);
		cq.where(cb.equal(root.get("name"), name));
		return entityManager.createQuery(cq).getSingleResult();
	}
	
	@Override
	public	void update(Category category){
		entityManager.merge(category);
	}
}
